package sing.core.util;

import android.app.Activity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Call;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import sing.core.Global;

/**
 * @ClassName: DownLoadUtil
 * @Description: 网络文件下载工具类
 */
public class DownLoadUtil {

    //下载路径
    private String localPath;
    private String url;
    private Activity activity;
    private long total = 0;
    private long sum = 0;

    public DownLoadUtil(Activity activity, String url) {
        String apkName = url.substring(url.lastIndexOf("/") + 1);
        String apkLocalDir = Global.INSTANCE.getDownloadPath();
        File apkFile = new File(apkLocalDir,apkName);
        this.localPath = apkFile.getPath();

        this.url = url;
        this.activity = activity;
    }

    //当前进度
    public int progress;
    static OkHttpClient mOkHttpClient = getUnsafeOkHttpClient();

    public boolean isExit = false;

    public void exit() {
        isExit = true;
    }

    public void downLoadFile(final Callback callback) {
        progress = 0;
        isExit = false;

        File apkFile = new File(localPath);
        if (apkFile.exists() && apkFile.isFile()){
            callback.success(url,localPath);
            return;
        }

        Request request = new Request.Builder().url(url).build();
        mOkHttpClient.newCall(request).enqueue(new okhttp3.Callback() {

            @Override
            public void onFailure(Call call, final IOException e) {
                new File(localPath).delete();
                activity.runOnUiThread(() -> callback.failure(url, e.toString()));
            }

            @Override
            public void onResponse(Call call, Response response) {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    is = response.body().byteStream();
                    total = response.body().contentLength();
                    File file = new File(localPath);
                    fos = new FileOutputStream(file);
                    while ((len = is.read(buf)) != -1 && !isExit) {
                        fos.write(buf, 0, len);
                        sum += len;
                        progress = (int) (sum * 100 / total);
                        if (!isExit) {
                            activity.runOnUiThread(() -> callback.process(sum, total));
                        } else {
                            break;
                        }
                    }
                    fos.flush();
                    if (!isExit) {
                        activity.runOnUiThread(() -> callback.success(url, localPath));
                    }
                } catch (final Exception e) {
                    activity.runOnUiThread(() -> {
                        new File(localPath).delete();
                        callback.failure(url, e.toString());
                    });
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException ignored) {
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException ignored) {
                    }
                }
            }
        });
    }

    public interface Callback {
        //成功回调
        void success(String url, String localPath);

        void failure(String url, String errorMsg);

        void process(long current, long total);
    }

    public static OkHttpClient getUnsafeOkHttpClient() {
        try {
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.connectionPool(new ConnectionPool(20, 20, TimeUnit.MINUTES));
            builder.sslSocketFactory(sslSocketFactory);

            builder.hostnameVerifier((hostname, session) -> true);

            return builder.build();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}